import json
import datetime
import asyncio
from package.connector.elastic_db import es_db
from common.analyzer_common.search import DISearch
from model.model import SearchHistory, SearchFavorite


class SearchView(SearchHistory):
    """搜索"""
    @classmethod
    def _remove_earliest_history(session, days=30):
        """只保留30天内历史搜索"""
        earliest = datetime.datetime.utcnow() - datetime.timedelta(days=days)
        SearchHistory.delete_items(session=session, filter_=[SearchHistory.created_at <= earliest])

    @classmethod
    def search_data(cls, search):
        """直接搜索"""
        return DISearch.search(search)
    
    @classmethod
    def create_search_task(cls, search):
        """创建搜索任务"""
        indices, query = DISearch.build_query(**search)
        async_task = es_db.async_op('submit', index=indices, body=query, size=1, timeout='10s') 
        return async_task
    
    @classmethod
    def get_search_task(cls, task_id):
        """获取搜索任务结果"""
        async_task = es_db.async_op('get', id=task_id, ignore=[404])
        if async_task.get('status') in (400, 404):
            return {}
        return async_task
    
    @classmethod
    def delete_search_task(cls, task_id=None):
        """清除搜索任务"""
        if task_id:
            async_del = es_db.async_op('delete', id=task_id, ignore=[404, 400])
            if async_del.get('acknowledged'):
                return True
            if async_del.get('status') in (400, 404):
                return True
        return False

    @classmethod
    async def search_websocket(cls, search, ws):
        """websocket 搜索方式"""
        try:
            async for process in DISearch.async_search(search):
                task_id = process.get('id', None)
                await ws.send_text(json.dumps(process, ensure_ascii=False))

            while True:  # 保持链接
                await asyncio.sleep(3)
                await ws.send_text(json.dumps({'status': 'done', 'task_id': task_id}, ensure_ascii=False))

        except Exception as e:
            cls.delete_search_task(task_id)

    
    @classmethod
    def record_history(cls, session, search):
        """记录搜索历史 并清理老搜索条件"""
        history = SearchHistory(search=search)
        session.add(history)
        session.commit()
        cls._remove_earliest_history(session)


class SearchFavoriteView(SearchFavorite):
    pass 
